package com.atlin.project.service.impl;


import cn.hutool.core.util.ObjectUtil;
import com.atlin.project.common.ErrorCode;
import com.atlin.project.contant.CommonConstant;
import com.atlin.project.exception.BusinessException;
import com.atlin.project.exception.ThrowUtils;
import com.atlin.project.mapper.NotificationMapper;
import com.atlin.project.model.domain.Notification;
import com.atlin.project.model.dto.notification.NotificationQueryRequest;
import com.atlin.project.model.vo.NotificationSdkVO;
import com.atlin.project.model.vo.NotificationVO;
import com.atlin.project.service.NotificationService;
import com.atlin.project.utils.SqlUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author atlin
 * @description 针对表【notification(通知信息表)】的数据库操作Service实现
 * @createDate 2024-06-06 22:28:42
 */
@Service
@Slf4j
public class NotificationServiceImpl extends ServiceImpl<NotificationMapper, Notification>
        implements NotificationService {

    @Override
    public void validNotification(Notification notification, List<String> domainList, boolean add) {
        Long id = notification.getId();
        String title = notification.getTitle();
        String content = notification.getContent();
        Date startTime = notification.getStartTime();
        Date endTime = notification.getEndTime();

        if (ObjectUtil.isNull(startTime) || ObjectUtil.isNull(endTime)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "开始时间或结束时间为空");
        }

        if (add) {
            ThrowUtils.throwIf(StringUtils.isAnyBlank(title, content), ErrorCode.PARAMS_ERROR);
        }

        // 当前实例是否在指定的日期之后
        if (startTime.after(endTime)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "开始时间不能大于结束时间");
        }
        // 有参数则校验
        if (StringUtils.isNotBlank(title) && title.length() > 80) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "标题过长");
        }
        if (StringUtils.isNotBlank(content) && content.length() > 2048) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "内容过长");
        }

        // 校验域名是否已经存在公告
        if (!ObjectUtils.isEmpty(domainList)) {
            LambdaQueryWrapper<Notification> queryWrapper = Wrappers.lambdaQuery(Notification.class);
            // 若果不是添加接口，需要排除当前公告
            if (!add) {
                queryWrapper.ne(Notification::getId, notification.getId());
            }
            queryWrapper.and(wrapper ->
                    domainList.forEach(domain -> wrapper.or().like(Notification::getDomain, "\"" + domain + "\""))
            );
            long count = this.count(queryWrapper);
            log.info("repeat data count is:{}", count);
            ThrowUtils.throwIf(count > 0, ErrorCode.PARAMS_ERROR, "该域名已存在对应公告");
        }
    }

    @Override
    public NotificationVO getNotificationVO(Notification notification, HttpServletRequest request) {
        return NotificationVO.objToVo(notification);
    }

    @Override
    public NotificationSdkVO getNotificationSdkVO(Notification notification) {
        if (notification == null) {
            return null;
        }
        NotificationSdkVO notificationSdkVO = new NotificationSdkVO();
        BeanUtils.copyProperties(notification, notificationSdkVO);
        return notificationSdkVO;
    }

    @Override
    public QueryWrapper<Notification> getQueryWrapper(NotificationQueryRequest questionQueryRequest) {
        QueryWrapper<Notification> queryWrapper = new QueryWrapper<>();
        if (questionQueryRequest == null) {
            return queryWrapper;
        }
        Long id = questionQueryRequest.getId();
        String title = questionQueryRequest.getTitle();
        String content = questionQueryRequest.getContent();
        Date startTime = questionQueryRequest.getStartTime();
        Date endTime = questionQueryRequest.getEndTime();
        String userId = questionQueryRequest.getUserId();
        Integer status = questionQueryRequest.getStatus();
        List<String> domains = questionQueryRequest.getDomain();
        String sortField = questionQueryRequest.getSortField();
        String sortOrder = questionQueryRequest.getSortOrder();

        queryWrapper.eq(ObjectUtils.isNotEmpty(id), "id", id);
        queryWrapper.like(StringUtils.isNotBlank(title), "title", title);
        queryWrapper.like(StringUtils.isNotBlank(content), "content", content);
        queryWrapper.ge(startTime != null, "startTime", startTime);
        queryWrapper.le(endTime != null, "endTime", endTime);
        queryWrapper.eq(ObjectUtils.isNotEmpty(userId), "userId", userId);
        queryWrapper.eq(ObjectUtils.isNotEmpty(status), "status", status);
        if (!CollectionUtils.isEmpty(domains)) {
            for (String domain : domains) {
                queryWrapper.like("domain", domain);
            }
        }

        queryWrapper.eq("isDelete", false);
        queryWrapper.orderBy(SqlUtils.validSortField(sortField),
                sortOrder.equals(CommonConstant.SORT_ORDER_ASC), sortField);
        return queryWrapper;
    }

    @Override
    public Page<NotificationVO> getNotificationVOPage(Page<Notification> questionPage, HttpServletRequest request) {
        List<Notification> notificationList = questionPage.getRecords();
        Page<NotificationVO> notificationVOPage = new Page<>(questionPage.getCurrent(), questionPage.getSize(), questionPage.getTotal());
        if (CollectionUtils.isEmpty(notificationList)) {
            return notificationVOPage;
        }
        // 填充信息
        List<NotificationVO> notificationVOList = notificationList.stream().map(NotificationVO::objToVo).collect(Collectors.toList());
        notificationVOPage.setRecords(notificationVOList);

        return notificationVOPage;
    }
}




